﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace GitDiff
{
    public partial class Form1 : Form
    {
        #region 预定义
        private SystemParam sysParam = new SystemParam();
        private const string GIT_COMMAND_STRING_HELP = "git help";
        private const string GIT_COMMAND_STRING_GET_STATUS = "git status -s";
        private const string GIT_COMMAND_STRING_GET_SHOW_HEAD = "git show head:";
        private const string GIT_COMMAND_STRING_CHECKOUT_HEAD = "git checkout -- ";
        private const string GIT_COMMAND_STRING_CHECKOUT_STASH = "git checkout -- .";
        private const string GIT_FILE_STATUS_HEAD_ADD = "?? ";
        private const string GIT_FILE_STATUS_HEAD_MODIFY = " M ";
        private const string GIT_FILE_STATUS_HEAD_DELETE = " D ";
        private const string TMP_FOLDER_NAME = "_tmp_gitdiff_files";
        private enum CommandType
        {
            NONE = 0,
            CMD_GET_STATUS,                         // 获取文件状态
            CMD_GET_SHOW_HEAD,                      // 读取最近历史版本
            CMD_GET_SHOW_HEAD_TO_DIRECTION_FILE,    //
            CMD_GET_CHECKOUT_HEAD,                  //
            CMD_GET_CHECKOUT_STASH                  //
        };

        private string strSourcePath = string.Empty;
        private string strDirectionPath = string.Empty;
        private List<string> lAddFile = new List<string>();
        private GitDiffOperation oDiffOperate = new GitDiffOperation();
        #endregion

        public Form1()
        {
            InitializeComponent();
            initControl();
        }

        /// <summary>
        /// 初始化窗体控件
        /// </summary>
        private void initControl()
        {
            txtSourcePath.Text = String.Empty;
            txtDirectPath.Text = String.Empty;
            ////txtModifyFileList.Text = string.Empty;

            txtSourcePath.Focus();
        }

        /// <summary>
        /// 检索修改文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            string strMessage = string.Empty;
            string strFileList = string.Empty;
            // 输入锁定
            LockInputControls();

            try
            {
                // 校验窗体控件输入数据有效性
                if (!checkInputVaild(out strSourcePath, out strDirectionPath))
                {
                    // 输入锁定
                    ReleaseInputControls();
                    return;
                }

                // 获取异常状态文件一览
                if (!oDiffOperate.getModeifyFileList(strSourcePath, out strMessage, out strFileList))
                {
                    if (!string.IsNullOrWhiteSpace(strMessage))
                        MessageBox.Show(strMessage);
                    else
                        MessageBox.Show("系统异常");

                    ReleaseInputControls();
                    return;
                }
                else
                {
                    //txtModifyFileList.Text = strFileList;

                    lstFileList.Items.Clear();
                    string[] sResultArr = null;
                    if (!string.IsNullOrWhiteSpace(strFileList))
                        sResultArr = strFileList.Replace(sysParam.NewLineStr, "|").Split('|');

                    if(sResultArr.Length > 0)
                    {
                        foreach(var item in sResultArr.ToList())
                        {
                            if (string.IsNullOrWhiteSpace(item)) continue;
                            lstFileList.Items.Add(item);
                        }
                    }
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            // 输入锁定释放
            ReleaseInputControls();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            if (lstFileList.Items.Count == 0)
            {
                MessageBox.Show("请先获取修正后文件列表");
                return;
            }

            string strMessage = string.Empty;
            // 输入锁定
            LockInputControls();

            try
            {
                List<string> lFileList = new List<string>();
                // [操作用] 修正文件->迁移后目录 拷贝
                foreach(var q in lstFileList.Items)
                {
                    lFileList.Add(q.ToString());
                }
                if (!oDiffOperate.CopyModifyFile(lFileList, strSourcePath, strDirectionPath,out strMessage))
                    return;

                // [操作用] 修正前文件->迁移后目录 拷贝
                if (!oDiffOperate.CopyLastVersionFile(lFileList, strSourcePath, strDirectionPath, out strMessage))
                    return;
            }
            catch
            {
                // 输入锁定释放
                ReleaseInputControls();
                return;
            }

            MessageBox.Show("文件迁移成功！");

            // 输入锁定释放
            ReleaseInputControls();
        }

        /// <summary>
        /// 打开迁移前目录选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dilog = new FolderBrowserDialog();
            dilog.Description = "请选择文件夹";
            if (dilog.ShowDialog() == DialogResult.OK || dilog.ShowDialog() == DialogResult.Yes)
            {
                txtSourcePath.Text = dilog.SelectedPath;
            }
        }

        /// <summary>
        /// 打开迁移后目录选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dilog = new FolderBrowserDialog();
            dilog.Description = "请选择文件夹";
            if (dilog.ShowDialog() == DialogResult.OK || dilog.ShowDialog() == DialogResult.Yes)
            {
                txtDirectPath.Text = dilog.SelectedPath;
            }
        }

        /// <summary>
        /// 保存修正文件列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            SaveFileDialog dialog = new SaveFileDialog();
            string localFilePath = strDirectionPath; //获得文件路径 
            string fileNameExt = string.Format("GitModifyAutoSave_{0}", DateTime.Now.ToString("yyyyMMdd_HHmm")); //获取文件名，不带路径

            dialog.Filter = "(*.txt)|*.txt|(*.*)|*.*";
            dialog.AddExtension = true;
            dialog.RestoreDirectory = true;
            dialog.FileName = fileNameExt;
            dialog.InitialDirectory = localFilePath;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                FileStream fs = new FileStream(dialog.FileName, FileMode.Create);
                StreamWriter sw = new StreamWriter(fs);
                try
                {
                    sw.Write(lstFileList.ToString());
                    sw.Flush();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
                finally
                {
                    sw.Close();
                    fs.Close();
                }
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (lstFileList.Items.Count == 0)
            {
                MessageBox.Show("请先获取修正后文件列表");
                return;
            }

            string strMessage = string.Empty;
            // 输入锁定
            LockInputControls();

            try
            {
                List<string> lFileList = new List<string>();
                foreach(var q in lstFileList.Items)
                {
                    lFileList.Add(q.ToString());
                }
                // [操作用] 修正文件->迁移后目录 拷贝
                if (!oDiffOperate.CopyModifyFile(lFileList, strSourcePath, strDirectionPath, out strMessage))   
                {
                    MessageBox.Show(strMessage);
                    // 输入锁定释放
                    ReleaseInputControls();
                    return;
                }
            }
            catch
            {
                MessageBox.Show("文件迁移失败！");
                // 输入锁定释放
                ReleaseInputControls();

                return;
            }

            MessageBox.Show("文件迁移成功！");

            // 输入锁定释放
            ReleaseInputControls();
        }

        /// <summary>
        /// 历史记录保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            string sSubDirectionPath = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            bool bResult = History.Instance.HistroyXML();
            if(bResult)
            {
                List<string> subFile = new List<string>();
                foreach(var t in lstFileList.Items)
                {
                    subFile.Add(t.ToString());
                }

                History.HistoryEntity entity = new History.HistoryEntity
                {
                    NewDirectionPath = txtDirectPath.Text,
                    OldDirectionPath = txtSourcePath.Text,
                    SaveDate = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                    SubFile = string.Join(",", subFile),
                    FileName = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")
                };
                History.Instance.WriteSetting(entity);
            }
        }

        /// <summary>
        /// [右键菜单]
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lstFileList_DoubleClick(object sender, EventArgs e)
        {
            ListBox lEventControl = (ListBox)sender;
            if (null != lEventControl)
                lEventControl.Items.Remove(lEventControl.SelectedItem);
        }
        /// <summary>
        /// [右键菜单]显示修正内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 显示修正ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(lstFileList.SelectedItems.Count > 1)
            {
                MessageBox.Show("只能选择一个文件进行显示！");
                return;
            }

            var t = lstFileList.SelectedItem;
        }

        /// <summary>
        /// [右键菜单]还原修改版本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 还原修正版本ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lstFileList.SelectedItems.Count == 0)
            {
                MessageBox.Show("请选择待还原的文件！");
                return;
            }

            foreach(var item in lstFileList.SelectedItems)
            {
                item.ToString();
                //oDiffOperate.RevertModifyFile();
            }
        }

        #region 扩展函数
        /// <summary>
        /// 校验输入输出文件路径的有效性
        /// </summary>
        /// <returns></returns>
        private bool checkInputVaild(out string strSourcePath, out string strDirectionPath)
        {
            bool bResult = false;
            strSourcePath = string.Empty;
            strDirectionPath = string.Empty;

            Regex reg = new Regex(@"^(?<path>(?:[a-zA-Z]:)?\\(?:[^\\\?\/\*\|<>:]+\\)+)");

            try
            {
                #region 迁移源目录验证
                if (string.IsNullOrWhiteSpace(txtSourcePath.Text.Trim()))
                {
                    MessageBox.Show("请输入需要进行处理的项目目录");
                    txtSourcePath.Focus();
                    return bResult;
                }

                strSourcePath = txtSourcePath.Text.Trim();

                if (!reg.IsMatch(strSourcePath))
                {
                    MessageBox.Show("输入的处理的目录格式有误，请确认！");
                    txtSourcePath.Focus();
                    return bResult;
                }
                #endregion

                #region 迁移后目录验证
                if (string.IsNullOrWhiteSpace(txtDirectPath.Text.Trim()))
                {
                    MessageBox.Show("请输入迁移后的项目目录");
                    txtDirectPath.Focus();
                    return bResult;
                }

                strDirectionPath = txtDirectPath.Text.Trim();

                if (!reg.IsMatch(strDirectionPath))
                {
                    MessageBox.Show("输入的迁移后项目目录格式有误，请确认！");
                    txtDirectPath.Focus();
                    return bResult;
                }

                //如果不存在就创建文件夹
                if (Directory.Exists(strDirectionPath) == false)
                    Directory.CreateDirectory(strDirectionPath);
                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show("系统执行异常：" + ex.Message);
                return false;
            }

            bResult = true;
            return bResult;
        }
        #endregion

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void LockInputControls()
        {
            txtSourcePath.Enabled = false;
            txtDirectPath.Enabled = false;
        }

        private void ReleaseInputControls()
        {
            txtSourcePath.Enabled = true;
            txtDirectPath.Enabled = true;
        }
    }
}
